<template>
  <div class="hotel-week-pre-accuracy">
    <!-- <div class="top-section">
      <div class="header-wrapper">
        <h3 class="title">酒店月度预测准确率</h3>
      </div>
    </div> -->
    <div class="main-content">
      <TableCard
        class="card-flex-all"
        title="月度预测准确率"
        :dataList="dataList"
        :columns="this.dataColumns"
        :scroll="tableHigh"
        :summary="summaryData"
        :exportData="dataList"
        :loading="loading"
        :isPagination="false"
      >
        <template #hotelName="{ text }">
          <span v-if="checkTag(text)" class="main-content-title-custom">{{ text }}</span>
          <span v-else>{{ text }}</span>
        </template>
        <template #month="{ text, col }">
          <span :class="getColorClass(text, col)">{{ percent2DFormatter(text) }}</span>
        </template>
      </TableCard>
    </div>
  </div>
</template>

<script>
  import dayjs from 'dayjs';
  import * as MathUtil from '/@/utils/MathUtil';
  import * as DateUtil from '/@/utils/dateUtil';
  import TableCard from '/@/views/applications/ui/TableCard.vue';
  import { defHttp } from '/@/utils/http/axios';

  const THRESHOLD_LOW = -0.05;
  const THRESHOLD_HIGHT = 0.05;

  export default {
    name: 'HotelWeekPreAccuracy',

    components: {
      TableCard,
    },

    data() {
      return {
        loading: false,
        currentMonth: dayjs(),
        currentWeek: 1,
        hotelList: [],
        currentCode: '',
        subjectList: [],
        dataList: [],
        monthList: DateUtil.generateMonthList(),
        weekList: DateUtil.generateWeekList().map((w) => ({
          label: `第${w}周`,
          value: w,
        })),
        tableHigh: { x: '100%', y: 'calc(60vh)' },
        sumKeys: [],
        colKeys: ['hotelCode', 'hotelName'],
        dataColumns: [],
        isDetail: false,
        showFilter: false,
        searchFormOptions: [
          {
            value: 'dateslot',
            label: '预测月份',
            selected: true,
            showDetails: true,
          },
          {
            value: 'weekslot',
            label: '周',
            selected: true,
            showDetails: true,
          },
          {
            value: 'detail',
            label: '展示详细列',
            selected: true,
            showDetails: true,
          },
        ],
        exportHeader: [],
        showSubject: [],
        sortSubjectCode: null,
      };
    },

    created() {
      defHttp.get({ url: '/data/hotel/list' }, { isTransformResponse: false }).then((res) => {
        if (res.code === 200 && res.result.length > 0) {
          const data = res.result;
          this.hotelList = data;
          this.currentCode = data.map((d) => d.code).join(',');
          this.dataColumns = this.getDataColumns();
          this.monthList.forEach((m) => {
            this.colKeys.push(`p${m.value}`);
            this.sumKeys.push(`p${m.value}`);
            this.colKeys.push(`a${m.value}`);
            this.sumKeys.push(`a${m.value}`);
            this.colKeys.push(m.value);
          });
          this.fetchBaseInfo();
        }
      });
    },

    methods: {
      fetchBaseInfo() {
        this.loading = true;
        defHttp
          .post({
            url: '/data/query',
            data: {
              labelCode: 'getHotelIncomeLastWeekPreAct',
              sqlParams: [
                {
                  key: 'code',
                  value: this.currentCode,
                },
              ],
              pageIndex: 1,
              pageSize: 5000,
            },
          })
          .then((res) => {
            if (res.datas.success && res.datas.totalCount > 0) {
              const incomeList = res.datas.data;
              const hotelData = this.hotelList.map((h) => {
                let d = {
                  hotelCode: h.code,
                  hotelName: h.name,
                };
                this.monthList
                  .map((m) => m.value)
                  .forEach((m) => {
                    d[`p${m}`] = null;
                    d[`a${m}`] = null;
                    incomeList.forEach((i) => {
                      if (i.calMonth.slice(-2) === m && i.hotelCode === h.code) {
                        d[`p${m}`] = Math.round(i.preFvalue);
                        d[`a${m}`] = Math.round(i.actualFvalue);
                      }
                    });
                  });
                this.wrapData(d);
                return d;
              });

              const hotelMap = this.hotelList.reduce((acc, hotel) => {
                if (incomeList.filter((d) => d.hotelCode === hotel.code).length > 0) {
                  const key = hotel.hpositionName;
                  if (!acc[key]) {
                    acc[key] = [];
                  }
                  acc[key] = acc[key].concat(hotelData.filter((d) => d.hotelCode === hotel.code));
                }
                return acc;
              }, {});

              let dataList = [];
              Object.keys(hotelMap).forEach((key) => {
                const pDataList = hotelMap[key];
                dataList = dataList.concat(pDataList);
                // 动态生成初始值对象
                const initialTotals = this.colKeys
                  .filter((c) => c !== 'hotelName')
                  .reduce(
                    (acc, field) => {
                      acc[field] = 0;
                      return acc;
                    },
                    { hotelName: `${key}酒店小计` }
                  );

                const subSum = pDataList.reduce((acc, hotel) => {
                  this.sumKeys.forEach((field) => {
                    acc[field] += Number(hotel[field]);
                  });
                  return acc;
                }, initialTotals);
                this.wrapData(subSum);
                dataList.push(subSum);
              });
              this.dataList = dataList;
            } else {
              this.dataList = [];
            }
            this.loading = false;
          })
          .catch((error) => {
            console.error('获取数据失败：', error);
            this.loading = false;
            this.dataList = [];
          });
      },

      wrapData(data) {
        this.monthList
          .map((m) => m.value)
          .filter((m) => m < this.currentMonth.format('MM'))
          .forEach((m) => {
            data[m] = this.safeDivide(data[`a${m}`], data[`p${m}`]) - 1;
          });
        const values = this.monthList
          .map((m) => m.value)
          .filter((m) => m < this.currentMonth.format('MM'))
          .map((m) => data[m]);
        data['accurateTimes'] = values.filter((v) => v >= THRESHOLD_LOW && v <= THRESHOLD_HIGHT).length;
        data['hightTimes'] = values.filter((v) => v > THRESHOLD_HIGHT).length;
        data['lowTimes'] = values.filter((v) => v < THRESHOLD_LOW).length;
        data['accurateRate'] = data['accurateTimes'] / this.currentMonth.month();
      },

      summaryData() {
        const initialTotals = this.colKeys
          .filter((c) => c !== 'hotelName' && c !== 'hotelCode')
          .reduce(
            (acc, field) => {
              acc[field] = 0;
              return acc;
            },
            { hotelName: '合计' }
          );
        const d = this.dataList
          .filter((d) => d.hotelName.includes('小计'))
          .reduce((sum, item) => {
            this.sumKeys.forEach((field) => {
              sum[field] += Number(item[field]);
            });
            return sum;
          }, initialTotals);
        this.wrapData(d);
        this.customRenderData(d, this.dataColumns);
        return [d];
      },

      customRenderData(data, columns) {
        columns.forEach((c) => {
          if (c.customRender) {
            const value = { text: data[c.dataIndex] };
            data[c.dataIndex] = c.customRender(value);
          }
          if (c.customRenderTemp) {
            const value = { text: data[c.dataIndex] };
            data[c.dataIndex] = c.customRenderTemp(value);
          }
          if (c.children) {
            this.customRenderData(data, c.children);
          }
        });
      },

      getDataColumns() {
        let dataColumns = [
          {
            title: '项目名称',
            dataIndex: 'hotelName',
            key: 'hotelName',
            width: 220,
            align: 'left',
            ellipsis: true,
            fixed: 'left',
            scopedSlots: {
              customRender: 'hotelName',
            },
          },
        ];
        dataColumns = dataColumns
          .concat(
            this.monthList.map((m) => {
              return {
                dataIndex: m.value,
                key: m.value,
                width: 120,
                align: 'right',
                title: m.name,
                customRenderTemp: (val) => this.percent2DFormatter(val.text),
                scopedSlots: {
                  customRender: 'month',
                },
              };
            })
          )
          .concat([
            {
              dataIndex: 'accurateTimes',
              key: 'accurateTimes',
              width: 120,
              align: 'right',
              title: '准确次数',
            },
            {
              dataIndex: 'hightTimes',
              key: 'hightTimes',
              width: 120,
              align: 'right',
              title: '超预测次数',
            },
            {
              dataIndex: 'lowTimes',
              key: 'lowTimes',
              width: 120,
              align: 'right',
              title: '差预测次数',
            },
            {
              dataIndex: 'accurateRate',
              key: 'accurateRate',
              width: 120,
              align: 'right',
              title: '准确率',
              customRender: (val) => this.percent2DFormatter(val.text),
            },
          ]);

        return dataColumns;
      },

      getColorClass(value, col) {
        if (value === null || value === undefined) return '';
        if (col.key === 'accurateRate') {
          return value >= 0.8 ? 'text-success' : value >= 0.6 ? 'text-warning' : 'text-danger';
        }
        return value >= THRESHOLD_LOW && value <= THRESHOLD_HIGHT ? 'text-success' : value > THRESHOLD_HIGHT ? 'text-warning' : 'text-danger';
      },

      checkTag(key) {
        return key.includes('小计');
      },

      percent2DFormatter(value) {
        return MathUtil.percent2DFormatter(value);
      },

      safeDivide(numerator, denominator) {
        return MathUtil.safeDivide(numerator, denominator);
      },

      getWeekOfMonth(date) {
        return Math.ceil(date.date() / 7);
      },

      handleSaveFilter(updatedFields) {
        this.selectedFields = updatedFields;
        this.searchFormOptions = updatedFields;

        // 更新表单显示
        const formWrapper = document.querySelector('.form-wrapper');
        if (formWrapper) {
          const hotelItem = formWrapper.querySelector('.form-item:nth-child(1)');

          if (hotelItem) {
            hotelItem.style.display = updatedFields.find((f) => f.value === 'hotel')?.selected ? 'flex' : 'none';
          }
        }

        // 重新查询数据
        this.fetchBaseInfo();
      },
    },
  };
</script>

<style lang="less" scoped>
  .hotel-week-pre-accuracy {
    display: flex;
    flex-direction: column;
    background-color: #fff;

    .top-section {
      background: #fff;
      padding: 24px 24px 0;
    }

    .header-wrapper {
      margin-bottom: 24px;

      .title {
        font-size: 18px;
        font-weight: 600;
        color: #1a253b;
        margin: 0;
        padding: 0;
      }
    }

    .main-content {
      flex: 1;
      background: @content-inside-bg;
      padding: 16px 0;
      overflow: hidden;

      .card-flex-all {
        height: 100%;
      }

      &-title-custom {
        color: #00b578;
        font-weight: 500;
      }
    }
  }

  .text-success {
    color: #52c41a;
  }

  .text-warning {
    color: #faad14;
  }

  .text-danger {
    color: #ff4d4f;
  }
</style>
